﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UIFramework;

public partial class UIBase : IUIBase
{
    /*
     depth备注：
     预制中，假设uiroot上配置的值是order，则子物体上的值配置为 order+n，n为所需的偏移值
     比如：uiroot上是1，则子物体组件应该是1+n。而实际运行时的值，uiroot上是 1+（“SetDepth(int depth)”中的）depth，子物体是1+depth+n

     动态实例化出来，需要修改depth的Item处理方法：
        1.实例化在 OnShow 中执行
        2.实例化后，调用 GetDepthComponents 获取该物体的depth列表 itemlist0
        3.重写方法 OnDepthChange，并在方法中处理depth变化
        例：
        
        List<UIDepthItem> itemlist0 = new List<UIDepthItem>();

        protected override void OnShow(params object[] paras)
        {
            ...
            实例化代码
            GetDepthComponentsNonAlloc(实例化item的父节点 ,itemlist0);
            ...
        }

        protected override void OnDepthChange(int depthDelta)
        {
            for (int i = 0; i < itemlist0.Count; i++)
            {
                itemlist0[i].ChangeDepth(depthDelta);
            }
        }
        
         */

    public int Depth;
    protected int _originalDepth;
    protected List<UIDepthItem> _depthItems = new List<UIDepthItem>();

    private void InitDepth() 
    {
        Depth = _originalDepth = RootTrans.GetComponent<Canvas>().sortingOrder;
        _depthItems = GetDepthComponents(RootTrans);
    }

    public sealed override void SetDepth(int depth)
    {
        Depth = depth + _originalDepth;
        for (int i = 0; i < _depthItems.Count; i++)
        {
            _depthItems[i].ChangeDepth(depth);
        }
        OnDepthChange(depth);
    }

    /// <summary>
    /// 此处不会调用resultList的Clear函数，如有需要自行调用
    /// </summary>
    /// <param name="targetTrans"></param>
    /// <param name="resultList"></param>
    public void GetDepthComponentsNonAlloc(Transform targetTrans, List<UIDepthItem> resultList)
    {
        if (targetTrans.GetComponent<UIDepthIgnore>() != null)
        {
            return;
        }

        Canvas[] allCanvas = targetTrans.GetComponentsInChildren<Canvas>(true);
        ParticleSystem[] particles = targetTrans.GetComponentsInChildren<ParticleSystem>(true);
        int count = 0;
        count += allCanvas != null ? allCanvas.Length : 0;
        count += particles != null ? particles.Length : 0;

        if (allCanvas != null && allCanvas.Length > 0)
        {
            AddDepthItem<Canvas, UIDepthItem_Canvas>(allCanvas, resultList);
        }

        if (particles != null && particles.Length > 0)
        {
            AddDepthItem<ParticleSystem, UIDepthItem_Particle>(particles, resultList);
        }
        return;
    }

    private void AddDepthItem<T, T1>(T[] array, List<UIDepthItem> result) where T : Component where T1 : UIDepthItem<T>
    {
        for (int i = 0; i < array.Length; i++)
        {
            var tmp = array[i];
            var item = tmp.GetComponent<UIDepthItem>();
            if (item == null)
            {
                item = tmp.gameObject.AddComponent<T1>();
                ((T1)item).Init(GetSortLayerName(), tmp);
            }
            result.Add(item);
        }
    }

    public List<UIDepthItem> GetDepthComponents(Transform targetTrans)
    {
        if (targetTrans.GetComponent<UIDepthIgnore>() != null)
        {
            return new List<UIDepthItem>(0);
        }

        Canvas[] allCanvas = targetTrans.GetComponentsInChildren<Canvas>(true);
        ParticleSystem[] particles = targetTrans.GetComponentsInChildren<ParticleSystem>(true);
        int count = 0;
        count += allCanvas != null ? allCanvas.Length : 0;
        count += particles != null ? particles.Length : 0;

        List<UIDepthItem> depthItems = new List<UIDepthItem>(count);

        if (allCanvas != null && allCanvas.Length > 0)
        {
            AddDepthItem<Canvas, UIDepthItem_Canvas>(allCanvas, depthItems);
        }

        if (particles != null && particles.Length > 0)
        {
            AddDepthItem<ParticleSystem, UIDepthItem_Particle>(particles, depthItems);
        }
        return depthItems;
    }

    protected string GetSortLayerName()
    {
        return UIFramework.UIUtility.GetSortLayerName(GetUICanvas());
    }

}
